# -*- coding: utf-8 -*-

import sys
import shutil
import os
import gettext

from kivy.app import App
from kivy.core.window import Window
from kivy.uix.widget import Widget
from kivy.uix.settings import Settings
from kivy.utils import platform

import model
from model.gamestate import Phase
from model.syssettings import SysSettings
from model.dictionary import Dictionary

from ui.welcome_screen import WelcomeScreen
from ui.add_player import AddPlayerScreen
from ui.add_words import AddWords
from ui.players_order import PlayersOrderWidget
from ui.from_to import FromToWidget
from ui.start_game import StartGame
from ui.guess_word import GuessWordScreen
from ui.presenter import Presenter
from ui.results_of_one_pair import ResultsOfOnePair
from ui.game_config import GameConfig
from ui.game_results import GameResults
from ui.before_round_screen import BeforeRoundScreen
from ui.quick_game_settings import QuickGameSettings
from ui.rules import RulesScreen
from ui.cur_result import CurResults
from ui.load_game import LoadGameScreen
from ui.edit_players import EditPlayers
from ui.join import Join

from kivy.logger import Logger


PATH = os.path.abspath('.')
LOCALE_PATH = os.path.join(PATH, 'locales')

CONFIG_FILE = PATH + '/data/config.ini'
CONFIG_TEMPLATE_FILE = PATH + '/data/config.ini.template'
PICKLED_GAMESTATE = PATH + '/data/pickled_gamestate.pkl'

gettext.bindtextdomain('thehat', LOCALE_PATH)


def check_config_version():
    with open(CONFIG_FILE, 'r') as config:
        conf_ver = config.readline()
        Logger.debug('config version is %s' % (conf_ver))
    with open(CONFIG_TEMPLATE_FILE, 'r') as template:
        temp_ver = template.readline()
        Logger.debug('config template version is %s' % (temp_ver))
    if conf_ver < temp_ver:
        shutil.copyfile(CONFIG_TEMPLATE_FILE, CONFIG_FILE)
        Logger.debug('config is out of date. replacing it with template')


class MainView(Widget):
    pass


class MainViewApp(App):
    title = 'The Hat'
    icon = 'assets/icon-small.png'

    def build(self):
        lang = gettext.translation('thehat', LOCALE_PATH, ['ru_RU'],
                                   codeset='utf-8')
        lang.install(True)
        self.main_view = MainView()
        self.presenter = Presenter(self.main_view, PATH)
        self.register_views()

        self.use_kivy_settings = False
        self.create_game_state_settings()
        self.config = None
        self.create_config()

        self.curr_orientation = Window.rotation
        self.prev_orientation = Window.rotation

        self.main_view.bind(on_keyboard=self.handle_keyboard)

        self.presenter.change_phase(Phase.WELCOME)
        return self.main_view

    def register_views(self):
        views = [
            (Phase.WELCOME, WelcomeScreen, ['welcomescreen']),
            (Phase.START_GAME, StartGame, ['startgame']),
            (Phase.GUESS_WORD, GuessWordScreen, ['guesswordscreen']),
            (Phase.ADD_PLAYER, AddPlayerScreen, ['addwords']),
            (Phase.ADD_WORDS, AddWords, ['addplayer']),
            (Phase.FROM_TO, FromToWidget, ['fromto']),
            (Phase.PLAYERS_ORDER, PlayersOrderWidget, ['playersorder']),
            (Phase.RESULTS_OF_ONE_PAIR, ResultsOfOnePair,
                ['resultsofonepair']),
            (Phase.GAME_CONFIG, GameConfig, ['gameconfig']),
            (Phase.BEFORE_ROUND, BeforeRoundScreen, ['beforeroundscreen']),
            (Phase.GAME_RESULTS, GameResults, ['gameresults']),
            (Phase.QUICK_GAME_SETTINGS, QuickGameSettings,
                ['quickgamesettings']),
            (Phase.RULES, RulesScreen, ['rules']),
            (Phase.CURRES, CurResults, ['curresults']),
            (Phase.LOAD_GAME, LoadGameScreen, ['loadgame']),
            (Phase.JOIN, Join, ['join']),
            (Phase.EDIT_PLAYERS, EditPlayers, ['editplayers'])]

        for view in views:
            self.presenter.register_view(*view)

    def create_game_state_settings(self):
        if (not hasattr(self.presenter.game_state, 'settings') or
                self.presenter.game_state.settings is None):
            self.presenter.game_state.settings = model.gamestate.Settings()

    def create_config(self):
        if self.config is None:
            self.load_config()
            Logger.debug('Loading config from ' +
                         self.get_application_config())
            self.config.read(self.get_application_config())
            Logger.debug('Loading settings data from %s' %
                         (PATH + '/ui/gameconfig.json',))

    def build_settings_menu(self):
        curr_phase = self.presenter.game_state.phase
        settings = self._app_settings

        if curr_phase == Phase.GUESS_WORD:
            return False
        if settings is not None and hasattr(settings, 'phase') and\
                settings.phase == curr_phase:
            self._app_settings = settings
            return True

        self._app_settings = None
        settings = super(MainViewApp, self)._create_settings()
        settings.phase = curr_phase

        panels = []
        panels.append((_('Interface settings'), PATH+'/ui/gameconfig.json'))
        panels.append((_('Sound settings'), PATH+'/ui/soundconfig.json'))

        select_dictionaries = False
        if curr_phase == Phase.WELCOME:
            panels.append((_('Quick-game settings'),
                          PATH+'/ui/defquickgameconfig.json'))
            panels.append((_('Game settings'),
                          PATH+'/ui/defgameconfig.json'))
            select_dictionaries = True

        for panel in panels:
            settings.add_json_panel(panel[0], self.config, panel[1])

        if select_dictionaries:
            settings.add_json_panel(_('Dictionaries settings'), self.config,
                                    data=str(Dictionary.make_json()))

        self._app_settings = settings
        return True

    def rotate_horizontally(self):
        horizontal_orientation =\
            self.presenter.settings.graphics.horizontal_orientation
        self.presenter.set_orientation(horizontal_orientation)

    def rotate_vertically(self):
        vertical_orientation =\
            self.presenter.settings.graphics.vertical_orientation
        self.presenter.set_orientation(vertical_orientation)

    def open_settings(self, *largs):
        self.rotate_horizontally()
        ret = self.build_settings_menu()
        return (ret and super(MainViewApp, self).open_settings(*largs))

    def close_settings(self, *largs):
        self.presenter.rotate()
        self.presenter.update()
        return super(MainViewApp, self).close_settings(*largs)

    def get_application_config(self):
        return CONFIG_FILE

    def on_config_change(self, config, section, key, value):
        self.config.write()
        attr = (section, key)

        self.presenter.settings.set_property(section, key, value)

        if section == 'Graphics':
            orientation =\
                self.presenter.settings.graphics.horizontal_orientation
            self.presenter.set_orientation(orientation)

    def on_pause(self):
        return self.presenter.close_app()

    def on_stop(self):
        return self.presenter.close_app()

    def handle_keyboard(self, window, key, *largs):
        if self.presenter.game_state.phase == Phase.GUESS_WORD:
            pass
        if (key == 27 or key == 1001):
            self.main_view.content.children[0].go_back()
            return True
        if key == 1002:
            if self.game_state.phase == WELCOME:
                on_pause()
            else:
                self.presenter.change_phase(Phase.WELCOME)
            return True

    def on_start(self):
        if platform() == 'android':
            import android

            android.map_key(android.KEYCODE_BACK, 1001)
            android.map_key(android.KEYCODE_HOME, 1002)

        self._app_window.bind(on_keyboard=self.handle_keyboard)
        self.presenter.resume_app()


if __name__ == "__main__":
    if not os.path.exists(CONFIG_FILE):
        Logger.warn('No config found')
        if not os.path.exists(CONFIG_TEMPLATE_FILE):
            raise Exception('No config files found')
        else:
            shutil.copyfile(CONFIG_TEMPLATE_FILE, CONFIG_FILE)

    if os.path.exists(CONFIG_FILE) and\
            os.path.exists(CONFIG_TEMPLATE_FILE):
        check_config_version()

    if not os.path.exists(PATH+'/statistics'):
        os.mkdir(PATH+'/statistics')

    if 'nocatch' in sys.argv:
        MainViewApp().run()
    else:
        try:
            MainViewApp().run()
        except Exception as msg:
            if os.path.exists(PICKLED_GAMESTATE):
                import datetime
                print('move pickle')
                now = datetime.datetime.now()
                time_stamp = now.strftime('%m.%d_%H.%M.%S')
                shutil.copyfile(PICKLED_GAMESTATE,
                                PICKLED_GAMESTATE+'.'+time_stamp)
                os.remove(PICKLED_GAMESTATE)
            if os.path.exists(CONFIG_FILE):
                os.remove(CONFIG_FILE)
            raise msg
